gtkwindow: Export our custom frame extents
authorJasper St. Pierre <jstpierre@mecheye.net>
Thu, 8 Aug 2013 20:29:02 +0000 (16:29 -0400)
committerJasper St. Pierre <jstpierre@mecheye.net>
Tue, 13 Aug 2013 14:38:49 +0000 (10:38 -0400)
This allows CSD windows to be maximized, tiled, and constrained
properly.

https://bugzilla.gnome.org/show_bug.cgi?id=705765

gdk/x11/gdkwindow-x11.c
gdk/x11/gdkx11window.h
gtk/gtkwindow.c

index 7a99d3098ba113e424ddcd4b775000646831cda2..d4ce45ce45d8ffec4799690da992382e4676c96e 100644 (file)
@@ -3601,6 +3601,45 @@ gdk_x11_window_set_hide_titlebar_when_maximized (GdkWindow *window,
     }
 }
 
+/**
+ * gdk_x11_window_set_frame_extents:
+ * @window: (type GdkX11Window): a #GdkWindow
+ * @left: The left extent
+ * @right: The right extent
+ * @top: The top extent
+ * @bottom: The bottom extent
+ *
+ * Newer GTK+ windows using client-side decorations use extra geometry
+ * around their frames for effects like shadows and invisible borders.
+ * Window managers that want to maximize windows or snap to edges need
+ * to know where the extents of the actual frame lie, so that users
+ * don't feel like windows are snapping against random invisible edges.
+ *
+ * Note that this property is automatically updated by GTK+, so this
+ * function should only be used by applications which do not use GTK+
+ * to create toplevel windows.
+ *
+ * Since: 3.10
+ */
+void
+gdk_x11_window_set_frame_extents (GdkWindow *window,
+                                  int        left,
+                                  int        right,
+                                  int        top,
+                                  int        bottom)
+{
+  Atom frame_extents;
+  gulong data[4] = { left, right, top, bottom };
+
+  frame_extents = gdk_x11_get_xatom_by_name_for_display (gdk_window_get_display (window),
+                                                         "_GTK_FRAME_EXTENTS");
+  XChangeProperty (GDK_WINDOW_XDISPLAY (window),
+                   GDK_WINDOW_XID (window),
+                   frame_extents, XA_CARDINAL,
+                   32, PropModeReplace,
+                   (guchar *) &data, 4);
+}
+
 /**
  * gdk_x11_window_set_theme_variant:
  * @window: (type GdkX11Window): a #GdkWindow
index 1503402eba0a608b2a13dcc27addd33a24c3a2c8..24bb853f75743f837acf472518c6e7487b1c7e84 100644 (file)
@@ -65,6 +65,12 @@ void     gdk_x11_window_set_utf8_property    (GdkWindow *window,
 GDK_AVAILABLE_IN_3_2
 void     gdk_x11_window_set_theme_variant (GdkWindow   *window,
                                            char        *variant);
+GDK_AVAILABLE_IN_3_10
+void     gdk_x11_window_set_frame_extents (GdkWindow *window,
+                                           int        left,
+                                           int        right,
+                                           int        top,
+                                           int        bottom);
 GDK_AVAILABLE_IN_3_4
 void     gdk_x11_window_set_hide_titlebar_when_maximized (GdkWindow *window,
                                                           gboolean   hide_titlebar_when_maximized);
index eb5fc18b6fbd3d4d038a4dff44633e5c92a08784..a0c0cc6ed3549a0329bb81b4ebe11254482c689a 100644 (file)
@@ -6390,6 +6390,24 @@ update_border_windows (GtkWindow *window)
     }
 }
 
+static void
+update_frame_extents (GtkWindow *window,
+                      GtkBorder *border)
+{
+#ifdef GDK_WINDOWING_X11
+  GdkWindow *gdk_window;
+
+  gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
+
+  if (GDK_IS_X11_WINDOW (gdk_window))
+    gdk_x11_window_set_frame_extents (gdk_window,
+                                      border->left,
+                                      border->right,
+                                      border->top,
+                                      border->bottom);
+#endif
+}
+
 /* _gtk_window_set_allocation:
  * @window: a #GtkWindow
  * @allocation: the original allocation for the window
@@ -6435,6 +6453,9 @@ _gtk_window_set_allocation (GtkWindow           *window,
 
   priv->title_height = 0;
 
+  if (priv->client_decorated)
+    update_frame_extents (window, &window_border);
+
   if (priv->title_box != NULL &&
       priv->decorated &&
       !priv->fullscreen)